package gu.simplemq;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import java.util.Iterator;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;

import gu.simplemq.utils.SPIUtils;

public class MessageQueueConfigManagers {

	private static volatile ImmutableMap<MessageQueueType, IMessageQueueConfigManager> managers;
	private static volatile IMessageQueueConfigManager defaultManager;
	private MessageQueueConfigManagers() {
	}
	/**
	 * 设置默认{@link IMessageQueueConfigManager}实例<br>
	 * 仅当默认实例未初始化(为{@code null})且输入参数不为{@code null}时有效(返回{@code true})
	 * 如果默认实例已经初始化,则输出警告日志,返回{@code false}
	 * @param defaultManager 为{@code null}返回{@code false}
	 * @return  设置成功返回{@code true},否则返回{@code false}
	 */
	public static boolean setDefaultManager(IMessageQueueConfigManager defaultManager){
		if(MessageQueueConfigManagers.defaultManager == null){
			synchronized (MessageQueueConfigManagers.class) {
				if(MessageQueueConfigManagers.defaultManager == null){
					if(defaultManager != null){
						MessageQueueConfigManagers.defaultManager = defaultManager;
						return true;
					}else {
						SimpleLog.log("input argument 'defaultFactory' is null");
						return false;
					}
				}
			}
		}
		SimpleLog.log("INVALID INVOCATION,default manager was initialized already before this invocation");
		return false;
	}
	/**
	 * 返回默认实例,如果 {@link #defaultManager}为null则抛出异常
	 * @return {@link IMessageQueueConfigManager}实例
	 * @throws NullPointerException 默认实例未初始化
	 */
	public static IMessageQueueConfigManager getDefaultManager() {		
		return checkNotNull(defaultManager,"defaultManager is uninitialized");
	}

	public static ImmutableMap<MessageQueueType, IMessageQueueConfigManager> getManagers(){
		
		if(managers == null){
			synchronized (MessageQueueConfigManagers.class) {
				if(managers == null){
					ImmutableMap.Builder<MessageQueueType, IMessageQueueConfigManager> builder = ImmutableMap.builder();
					/* SPI(Service Provider Interface)机制加载 {@link IMessageQueueConfigManager}实例,没有找到则抛出异常 */
					Iterator<IMessageQueueConfigManager> itor = SPIUtils.serviceLoaderOf(IMessageQueueConfigManager.class).iterator();
					int count =0;
					IMessageQueueConfigManager manager = null;
					while (itor.hasNext()) {
						manager = itor.next();
						builder.put(manager.getImplType(),manager);
						count ++;
					}
					checkState(count > 0, "NOT FOUND instance of %s" ,IMessageQueueConfigManager.class.getName());
					managers = builder.build();
					if(count == 1){
						setDefaultManager(manager);
					}
				}
			}
		}
		return managers;
	}
	public static IMessageQueueConfigManager getManager(String implType){
		return getManager(MessageQueueType.valueOf(implType));
	}
	public static IMessageQueueConfigManager getManager(MessageQueueType implType){
		return checkNotNull(getManagers().get(implType),
				"INVALID impltype,AVAILABLE VALUES:%s",Joiner.on(".").join(getManagers().keySet()));
	}
}
